假设你有一个叫Book的模型和一个叫Category的模型。每本书只属于一个分类,用一个外键表示。因此你的模型设计如下:1
2
3
4
5
6class Category(models.Model):
name = models.CharFeild(max_length=128)
class Book(modesl.Model):
name = models.CharField(max_length=128)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
如果你有一个Book实例,你可以通过对应的field访问它的分类。并且,如果你有一个分类的实例,默认情况下Django会添加一个叫做”book_set”的属性,这个属性返回该分类下所有书的集合,因此可以进行如下操作:1
2
3
4
5from tst.models import Category, Book
category = Category.objects.get(pk=1)
print("Books in "+category.name)
for book in category.book_set.all():
print(book.name)
book_set是一个django默认给我们构造的属性,通过外键的related_name属性可以给这个属性换个名字,比如说如果用category = models.ForeighKey(Category, related_name='book_collection')
定义一个分类,我可以用category.book_collection.all()
而不是category.book_set.all()
。
大多数情况下都不需要修改related_name,而且django默认的x_set很好记。然而有一种情况下必须要用related_name:当你有多个从一个模型到另一个模型的外键时。这种情况下可能会产生冲突(因为django会尝试给同一个模型创建两个x_set属性)。
例如,如果我的Book模型如下(有一个分类和一个子分类):1
2
3
4class Book(models.Model):
name = models.CharField(max_length=128)
category = models.ForeignKey(Category)
sub_category = models.ForeignKey(Category)
于是模型不会生效除非你给一个(或两个)外键related_name属性,因此冲突就解决了。例如:1
2
3
4class Books(models.Model):
name = models.CharField(max_length=128)
category = models.ForeignKey(Category, related_name='book_category_set')
sub_category = models.ForeignKey(Category, related_name='book_sub_category_set')